#include "ej_bsp_mic.h"
/* board include*/
#include "board_includes.h"
#include "common_includes.h"

/* private define -------------------------------------------------------- */
/*mic数据输出开头丢掉的数据包数*/
#define MIC_DUT_IN_DUMP_PACKET	10

#define AUDIO_ADC_BUF_NUM        3	//mic_adc采样buf个数
#define AUDIO_ADC_IRQ_POINTS     256 //mic_adc采样长度（单位：点数）
#define AUDIO_ADC_CH			 1	//双mic通话
#define AUDIO_ADC_BUFS_SIZE      (AUDIO_ADC_BUF_NUM * AUDIO_ADC_IRQ_POINTS * AUDIO_ADC_CH)

struct audio_mic_hdl {
    struct audio_adc_output_hdl adc_output;
    struct adc_mic_ch mic_ch;
    s16 adc_buf[AUDIO_ADC_BUFS_SIZE];    //align 2Bytes
    cbuffer_t output_cbuf;
    u16 dump_packet;
};
/* private function prototypes ---------------------------------------------- */


/* private variables -------------------------------------------------------- */
static struct audio_mic_hdl *p_mic_hdl = NULL;
mic_datas_cbfn_t g_mic_datas_cbfn = NULL;


/* private function ---------------------------------------------- */
static void ___mic_datas_handle(void *priv, s16 *data, int len)
{
	if (g_mic_datas_cbfn)
	{
		g_mic_datas_cbfn(data,len);
	}
}
static int ej_bsp_mic_en(u8 mic_ch, u16 sr,
                 u16 gain0, u16 gain1, u16 gain2, u16 gain3,
                 void (*data_handler)(void *priv, s16 *data, int len))
{
    printf("mic ch : %d\n\n", mic_ch);
    if (mic_ch) {
        if (p_mic_hdl) {
            printf("p_mic_hdl re-malloc error\n");
            return -1;
        }
        p_mic_hdl = zalloc(sizeof(struct audio_mic_hdl));
        if (p_mic_hdl == NULL) {
            printf("audio mic zalloc failed\n");
            return -1;
        }
        /*打开mic电压*/
        audio_mic_pwr_ctl(MIC_PWR_ON);
        /*打开mic0*/
        if (mic_ch & BIT(0)) {
            printf("adc_mic0 open, sr:%d, gain:%d\n", sr, gain0);
            audio_adc_mic_open(&p_mic_hdl->mic_ch, mic_ch, &adc_hdl);
            audio_adc_mic_set_gain(&p_mic_hdl->mic_ch, gain0);
        }
        /*打开mic1*/
        if (mic_ch & BIT(1)) {
            printf("adc_mic1 open, sr:%d, gain:%d\n", sr, gain1);
            audio_adc_mic1_open(&p_mic_hdl->mic_ch, mic_ch, &adc_hdl);
            audio_adc_mic1_set_gain(&p_mic_hdl->mic_ch, gain1);
        }
#if (AUDIO_ADC_CH > 2)
        /*打开mic2*/
        if (mic_ch & BIT(2)) {
            printf("adc_mic2 open, sr:%d, gain:%d\n", sr, gain2);
            audio_adc_mic2_open(&p_mic_hdl->mic_ch, mic_ch, &adc_hdl);
            audio_adc_mic2_set_gain(&p_mic_hdl->mic_ch, gain2);
        }
        /*打开mic3*/
        if (mic_ch & BIT(3)) {
            printf("adc_mic3 open, sr:%d, gain:%d\n", sr, gain3);
            audio_adc_mic3_open(&p_mic_hdl->mic_ch, mic_ch, &adc_hdl);
            audio_adc_mic3_set_gain(&p_mic_hdl->mic_ch, gain3);
        }
#endif /*AUDIO_ADC_CH*/
        audio_adc_mic_set_sample_rate(&p_mic_hdl->mic_ch, sr);
        audio_adc_mic_set_buffs(&p_mic_hdl->mic_ch, p_mic_hdl->adc_buf,
                                AUDIO_ADC_IRQ_POINTS * 2, AUDIO_ADC_BUF_NUM);
        p_mic_hdl->adc_output.handler = data_handler;
        audio_adc_add_output_handler(&adc_hdl, &p_mic_hdl->adc_output);
        audio_adc_mic_start(&p_mic_hdl->mic_ch);
        /*清掉mic开头几包数据*/
        p_mic_hdl->dump_packet = MIC_DUT_IN_DUMP_PACKET;
    } else {
        if (p_mic_hdl) {
            audio_adc_mic_close(&p_mic_hdl->mic_ch);
            audio_adc_del_output_handler(&adc_hdl, &p_mic_hdl->adc_output);
            audio_mic_pwr_ctl(MIC_PWR_OFF);
            free(p_mic_hdl);
            p_mic_hdl = NULL;
        }
    }
    return 0;
}

/* public function ---------------------------------------------- */

void ej_bsp_mic_open(void)
{
    ej_bsp_mic_en(1,
                 AUDIO_MIC_SAMPLE_RATE,
                 AUDIO_MIC_GAIN,
                 0,
                 0,
                 0,
                 ___mic_datas_handle);
}

/*关闭mic*/
void ej_bsp_mic_close(void)
{
    /*关闭所有MIC*/
    ej_bsp_mic_en(0, 0,
                 0, 0, 0, 0,
                 NULL);	
}

void ej_bsp_mic_gain_set(uint16_t gain)
{
    if (p_mic_hdl) 
	{
        audio_adc_mic_set_gain(&p_mic_hdl->mic_ch, gain);
        audio_adc_mic1_set_gain(&p_mic_hdl->mic_ch, gain);
#if (AUDIO_ADC_CH > 2)
        audio_adc_mic2_set_gain(&p_mic_hdl->mic_ch, gain);
        audio_adc_mic3_set_gain(&p_mic_hdl->mic_ch, gain);
#endif /*AUDIO_ADC_CH*/
    }
}

void ej_bsp_mic_sample_rate_set(uint16_t sr)
{
	if (p_mic_hdl)
	{
		audio_adc_mic_set_sample_rate(&p_mic_hdl->mic_ch, sr);
	}
	
}
void ej_bsp_mic_datas_cbfn_set(mic_datas_cbfn_t mic_datas_cbfn)
{
	g_mic_datas_cbfn = mic_datas_cbfn;
}

